package com.chh2000day.mirai.plugin

import com.chh2000day.mirai.plugin.base.GroupMapper
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregister
import net.mamoe.mirai.console.command.CommandSender
import net.mamoe.mirai.console.command.CompositeCommand
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.event.events.NudgeEvent
import net.mamoe.mirai.event.globalEventChannel
import java.io.File
import kotlin.coroutines.resume

/**
 * @Author CHH2000day
 * @Date 2022/2/11 22:47
 **/
object NudgeHandlerPlugin :
    KotlinPlugin(JvmPluginDescription.loadFromResource()) {

    private lateinit var config: Config


    private val json = Json {
        prettyPrint = true
        ignoreUnknownKeys = true
    }
    private val configFile = File(configFolder, "config.json")

    override fun onEnable() {
        super.onEnable()
        NudgeCommandComplex.register()
        globalEventChannel().filterIsInstance(NudgeEvent::class).apply {
            subscribeAlways<NudgeEvent> {
                it.handleEvent()
            }
        }
        runBlocking {
            reloadConfig()
        }
    }

    override fun onDisable() {
        super.onDisable()
        NudgeCommandComplex.unregister()
    }

    private suspend fun NudgeEvent.handleEvent() {
        if (!config.enabled) {
            return
        }
        //过滤其它请求
        if (bot.id != this.target.id) {
            return
        }
        val applicableMessages = config.configs.filter { singleConfig ->
            singleConfig.groupList.any {
                GroupMapper.getIdByName(it) == this.subject.id
            }
        }
        applicableMessages.randomOrNull()?.apply {
            this@handleEvent.subject.sendMessage(
                this.content.parseCode(
                    this@handleEvent.subject,
                    this@handleEvent.from as? Member
                )
            )
        }
    }

    private suspend fun reloadConfig(): Boolean {
        return suspendCancellableCoroutine<Boolean> { suspendCancellableCoroutine ->
            configFile.readText(Charsets.UTF_8).apply {
                kotlin.runCatching {
                    config = json.decodeFromString(Config.serializer(), this)
                }.onFailure {
                    logger.error(it)
                    suspendCancellableCoroutine.resume(false)
                }.onSuccess {
                    suspendCancellableCoroutine.resume(true)
                }
            }
        }
    }

    object NudgeCommandComplex : CompositeCommand(this, "戳一戳", parentPermission = PERMISSION_ID.toPermission()) {
        @SubCommand("reload", "重载")
        suspend fun CommandSender.handleReload() {
            requireSuperAdminPermission {
                reloadConfig().also {
                    sendMessage("重载结果:$it")
                }
            }
        }
    }

    @Serializable
    data class SingleConfig(val content: String, val groupList: List<String>)

    @Serializable
    data class Config(val enabled: Boolean, val configs: List<SingleConfig>)
}